/*
    hipnet.h - (c) 2012 - hippy.
    Packet format for HipNet definitions.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 
                    Version 2, December 2004 

 Copyright (C) 2004 Sam Hocevar <sam@hocevar.net> 

 Everyone is permitted to copy and distribute verbatim or modified 
 copies of this license document, and changing it is allowed as long 
 as the name is changed. 

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 

  0. You just DO WHAT THE FUCK YOU WANT TO.
  
*/

/* This program is free software. It comes without any warranty, to
 * the extent permitted by applicable law. You can redistribute it
 * and/or modify it under the terms of the Do What The Fuck You Want
 * To Public License, Version 2, as published by Sam Hocevar. See
 * http://sam.zoy.org/wtfpl/COPYING for more details. */
 
 
#include <netinet/in.h>
#include <arpa/inet.h>


#define MAX_DATA_LENGTH     513
#define HIPNET_BUFFER_SIZE  1024
#define HIPNET_PORT 44779

enum hipnet_packet_type_e {
  HIPNET_PING = 'H' << 24 | 'I' << 16 | 'P' << 8 | 'P',
  HIPNET_PONG = 'H' << 24 | 'I' << 16 | 'P' << 8 | 'Y',
  HIPNET_DMX = 'H' << 24 | 'I' << 16 | 'P' << 8 | 'D',
}__attribute__((packed));

typedef enum hipnet_packet_type_e hipnet_packet_type_t;

/*
 * our ping packet is received from a controller, telling us our configuration
 * the controller sends a ping packet when it received a pon packet.
 * node(pong) --- > controller(gets pong from node, sends ping to node) ---> node(ping)
 */
struct hipnet_ping_s {
  uint32_t head;        // 'HIPP'
  uint8_t  srcnode;     // node type $00 is from controller, only controllers ping
  uint8_t  universe;   // $00 > $FF (the xlr we are talking with)
  uint8_t  mode;        // $00 = Controller is alive, hello!
                                 // $F0 = Configure device to OUTPUT mode (xlr is sending dmx)
                                 // $F1 = Configure device to INPUT mode (xlr is receiving dmx, 0 data size expected)    
                                 // $FF = Disable port (until an F1 or F0 is received)                          
} __attribute__((packed));

typedef struct hipnet_ping_s hipnet_ping_t;

/*
 * ping reply, only sent in response to ping
 */
struct hipnet_pong_s {
  uint32_t head;        // 'HIPY'
  uint8_t srcnode;     // node type $00 is from controller, $01 is from node
  uint8_t  universe;   // $00 > $FF (the xlr we are talking with)
  uint8_t  mode;        // $00 = Request config for this universe, expect a ping in reply
} __attribute__((packed));

typedef struct hipnet_pong_s    hipnet_pong_t;

/*
 * hipnet data packet 
 */
struct hipnet_data_s {
  uint32_t head;         // 'HIPD'
  uint8_t srcnode;      // node type $00 is from controller, $01 is from node
  uint8_t  universe;    // $00 > $FF (the xlr we are talking with)  
  uint8_t  mode;        // $00  - DMX OUT Frame / Set DMX OUT Mode (as to output to xlr)
                                 //  $01 - DMX IN Frame / Set to DMX IN Mode(as received from xlr)
                                 //  $0F - Disable port
                                 
                                 //  $F1 - RDM OUT Frame 
                                 //         -  If in OUTPUT mode, interleave this request with DMX output
                                 //         -  breifly turns line around and listens for a response
                                 //         - then resumes selected dmx mode (either in or out)
                                 //  $F2 - RDM Discovery Response Frame
                                 //  $FF - returned with no data if no response was received                                                                            
  uint16_t size;         // size of the data segment
  uint8_t  data[MAX_DATA_LENGTH]; // data, including START code :)
} __attribute__((packed));

typedef struct hipnet_data_s    hipnet_data_t;



int hipnet_sock;     // our UDP socket

struct hipnet_data_s packet;  // input buffer
struct hipnet_data_s outpacket; // output buffer


struct sockaddr_in    sockAddr_hipnet;
struct sockaddr_in    sockFrom_hipnet;
struct sockaddr_in    sockBcast_hipnet;


